﻿using QxFramework.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameControl;
using UnityEngine.Tilemaps;
namespace GameMap
{

    public class GameMapManager : ManagerBase<GameMapManager>
    {
        /// <summary>
        /// 可用于关卡起点的拼装平台列表
        /// </summary>
        public List<GameObject> UsableCombineBenchList = new List<GameObject>();
     //   List<string> UsableBench = new List<string>();

        /// <summary>
        /// 初始时给玩家的道具
        /// </summary>
        public List<GameObject> OriginCombineItemList = new List<GameObject>();
        public override void InitModules()
        {
            base.InitModules();
            Add<DataModule<ItemsData>>(new DataModule<ItemsData>(), new DataTypePair{fileName=Data.Instance.UserName,dataType=DataType.LevelItemsInfo});
         /*   var args = info as NewMapLoadArgs;
            if (args.isLoadFromLocal == false)
            {
                Get<IDataModule<ItemsData>>().GameData.UsersItems = args.userData;
            }*/
            Add<MapManager>(new MapManager(),Get<IDataModule<ItemsData>>().GameData);
            if (Get<IDataModule<ItemsData>>().GameData.UsersItems.Count == 0)
            {
                Get<IDataModule<ItemsData>>().GameData.UsersItems.Add(new UserItemPropertyData());
            }
            foreach(var x in Get<IDataModule<ItemsData>>().GameData.UsersItems)
            {
                Add<BagManager>(new BagManager(),x);
            }
          //  InitItemOnScene();
            MessageManager.Instance.Get<ItemMapEvent>().RegisterHandler(ItemMapEvent.MapToBench,MapToBench);
            MessageManager.Instance.Get<ItemMapEvent>().RegisterHandler(ItemMapEvent.BenchToMap, BenchToMap);

        }
        public string GetNewBenchName
        {
            get
            {
                var UsableBench = GameManager.Get<IDataModule<GameSettingData>>().GameData.UsableBenchList;
                if (UsableBench.Count == 0)
                {
                    Debug.LogError($"{this}无可用拼装平台");
                    return null;
                }
                var ans = UsableBench.Last<string>();
                UsableBench.Remove(ans);
                return ans;
            }
        }
        public void OriginLoad(bool LoadFromScene)
        {
            InitItemOnScene(LoadFromScene);
            LoadTileMap(LoadFromScene);
            if (LoadFromScene)
            {
                OrginBagLoad();
                LoadUserWithBenchPair();
            }
        }
        void LoadUserWithBenchPair()
        {
            GameManager.Get<IDataModule<GameSettingData>>().GameData.UserWithBenchPairs.Clear();
            foreach(var x in Get<IDataModule<ItemsData>>().GameData.UsersItems)
            {
                GameManager.Get<IDataModule<GameSettingData>>().GameData.UserWithBenchPairs.Add(new Tuple<string, Vector3Int>(x.UserName,
                    (GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(GameMapManager.Instance.GetNewBenchName)as PosFixedItemField).MeshPosition));
            }
        }
        void LoadTileMap(bool LoadFromScene)
        {
            var tileMap  =GameObject.Find("Tilemap").GetComponent<Tilemap>();
            if (tileMap == null)
            {
                return;
            }
            if (LoadFromScene)
            {

            var bounds = tileMap.cellBounds;
                for (int x = bounds.xMin; x <= bounds.xMax; x++)
                {
                    for (int y = bounds.yMin; y <= bounds.yMax; y++)
                    {
                        for (int z = bounds.zMin; z <= bounds.zMax; z++)
                        {
                            if (tileMap.GetTile(new Vector3Int(x, y, z)))
                            {
                          //      Debug.Log(tileMap.GetTile(new Vector3Int(x, y, z)));
                                MessageManager.Instance.Get<ItemMapEvent>().DispatchMessage(ItemMapEvent.CreateInMap, 
                                    this, new ItemCreateArgs(tileMap.GetTile(new Vector3Int(x, y, z)).name, 
                                    tileMap.GetCellCenterWorld(new Vector3Int(x, y, z)),(ItemField tp)=>
                                {
                                    (tp as PosFixedItemField).MeshPosition = new Vector3Int(x, y, z);
                                    (tp as TileMapItemField).TileMapSpritePath = "Texture/TileMap/" + tp.ItemName.Split('_')[0] + "/" + tileMap.GetSprite(new Vector3Int(x, y, z)).name;
                                    //如果有TileMap花纹,设置为不可破坏
                                   /* if(int.TryParse(tileMap.GetSprite(new Vector3Int(x, y, z)).name,out int t))
                                    {
                                    //    (tp as PosFixedItemField).Blood = -1;
                                    }*/
                                }
                                ));
                        /*        var tp = GameControl.GameManager.Get<GameControl.IItemInstantiateManager>().CreatItemField(tileMap.GetTile(new Vector3Int(x, y, z)).name);
                                if (tp == null)
                                {
                                    continue;
                                }
                                var sprite=tileMap.GetSprite(new Vector3Int(x, y, z));
                                //       var ttt = tileMap.GetTile(new Vector3Int(x, y, z));
                                //     TileData data = new TileData();
                                //   ttt.GetTileData(new Vector3Int(x, y, z),, ref data);

                                Debug.Log(tileMap.GetTile(new Vector3Int(x, y, z)).name+"_"+sprite);
                                (tp as PosFixedItemField).MeshPosition = new Vector3Int(x, y, z);
                                (tp as PosFixedItemField).Position = (tileMap.GetCellCenterWorld(new Vector3Int(x, y, z)));*/
                         //       Get<IMapManager>().SceneItems.Add(tp);
                            }
                        }
                    }
                }
            }
            Destroy(tileMap.transform.gameObject);
        }
        void OrginBagLoad()
        {
            foreach (var x in GameMapManager.Instance.OriginCombineItemList)
            {
                foreach (var y in Get<IDataModule<ItemsData>>().GameData.UsersItems)
                {

                    MessageManager.Instance.Get<ItemMapEvent>().DispatchMessage(ItemMapEvent.ToBag, this, new ItemMapArgs
                    {
                        User = y.UserName,
                        ItemName = GameControl.GameManager.Get<GameControl.IItemInstantiateManager>().CreatItemField(x.name).ItemName
                    }) ;
                }
            }
            return;
        }
        void InitItemOnScene(bool LoadFromScene)
        {
            var list = GameObject.FindObjectsOfType<Item>();
            foreach (var x in list)
            {
                if (LoadFromScene == false)
                {
                    ObjectPool.Recycle(x);
                    continue;
                }

                var tp = GameControl.GameManager.Get<GameControl.IItemInstantiateManager>().CreatItemField(x.name.Split('_')[0].Split('(')[0].Split(' ')[0],x);
                if (tp == null)
                {

                }
                x.ItemFieldSetting = tp;
                x.gameObject.name = tp.ItemName;
        //        if (x.GetComponent<CombinableItem>())
      //          {
                    x.OnAwake();
            //    }
                if (GameMapManager.Instance.UsableCombineBenchList.Contains(x.gameObject))
                {
                    GameManager.Get<IDataModule<GameSettingData>>().GameData.UsableBenchList.Add(tp.ItemName);
                }

                //危险操作
               Get<IMapManager>().SceneItems.Add(x.UploadInstanceField());
            }
        }

 

        EventArgs BenchToMap(object sender, EventArgs e)
        {
            var tp = e as ItemMapArgs;
            var item = Get<IBagManager>().ItemsInBench.Find(s => s.ItemName == tp.ItemName);
            Get<IBagManager>().ItemsInBench.Remove(item);
            item.MeshTransform = tp.MeshTransform;
            item.PhysicTransform = tp.PhysicTransform;
            item.Position = tp.Position;
            item.BelongingType = ItemBelongingType.Map;
            item.SetWhenToMap();
            Get<IMapManager>().SceneItems.Add(item);
            return null;
        }
        EventArgs MapToBench(object sender,EventArgs e)
        {
            var tp = e as ItemMapArgs;
            var field = Get<IMapManager>().SceneItems.Find(s => s.ItemName == tp.ItemName);
            if (field == null)
            {
                return null;
            }
            GameCombine.CombineManager.Get<GameCombine.IItemCombineManager>().RemoveJointAbout(field.ItemName);
            field.User = tp.User;
            Debug.Assert(field != null);
            (field as CombinableItemField).IsPlayer = true;

            Get<IMapManager>().SceneItems.Remove(field);
            (field as CombinableItemField).ClearWhenToBench();
            MessageManager.Instance.Get<ItemMapEvent>().DispatchMessage(ItemMapEvent.ToBag, this, new ItemMapArgs
            {
                User = field.User,
                ItemName = field.ItemName,
                //      ValuePos = new Vector3Int(int.Parse(s[1]), int.Parse(s[2]), 1),
            });
            var args = new ItemMapArgs
            {
                User = field.User,
                ItemName = field.ItemName,
                MeshTransform = (field as CombinableItemField).MeshTransform
            };
          //  args.MeshTransform.BenchMeshPos = new Vector3Int(int.Parse(s[1]), int.Parse(s[2]), 1);
            MessageManager.Instance.Get<ItemMapEvent>().DispatchMessage(ItemMapEvent.BagToBench, this, args);
            return null;
        }
    }

    [Serializable]
    class ItemsData:GameDataBase
    {
        public List<ItemField> ItemsInMap=new List<ItemField>();
        public List<UserItemPropertyData> UsersItems=new List<UserItemPropertyData>();
        public string CurrentScene=LevelManager.Instance.CurrentLevel;
       /* public ItemsData()
        {
            ItemsInMap = new List<ItemField>();
            UsersItems = new List<UserItemPropertyData>();
            UsersItems.Add(new UserItemPropertyData());
        }*/
    }
    [Serializable]
    public class UserItemPropertyData
    {
        public string UserName="";
        public List<CombinableItemField> ItemsInBench=new List<CombinableItemField>();
        public List<CombinableItemField> ItemsInbag=new List<CombinableItemField>();
       /* public UserItemPropertyData()
        {
            UserName ="";
            ItemsInbag = new List<CombinableItemField>();
            ItemsInBench = new List<CombinableItemField>();
        }*/
    }
    /// <summary>
    /// 物体目前所处环境,在地图上/背包里/拼装台上
    /// </summary>
    public enum ItemMapEvent
    {
        BagToBench,
        BenchToBag,
        ToBag,
        ChangeTransform,
        DeleteInBench,
        DeleteInMap,
        CreateInMap,
        BenchToMap,
        MapToBench

    }
    public class ItemCreateArgs:EventArgs
    {
        public string ItemName;
        public Vector2 Position;
        public Action<ItemField> ItemInit;
        public ItemCreateArgs(string name,Vector2 pos, Action<ItemField> init = null)
        {
            ItemName = name;
            Position = pos;
            ItemInit = init;
        }
    }
    public class ItemMapArgs : EventArgs
    {
        public string User;
        public string ItemName;
        //  public string UserName;
        public ItemMeshTransform MeshTransform;
        public ItemPhysicTransform PhysicTransform;
        public Vector3 Position;
    /*    public ItemMapArgs()
        {
            ItemName = "";
            MeshTransform = new ItemMeshTransform();
        }
        public ItemMapArgs(string name,Vector3Int pos)
        {
            ItemName = name;
            MeshTransform = new ItemMeshTransform();
            MeshTransform.BenchMeshPos = pos;
        }
        public ItemMapArgs(string name, int rotate)
        {
            ItemName = name;
            MeshTransform = new ItemMeshTransform();
            MeshTransform.MeshRotate=rotate;
        }
        public ItemMapArgs(string name,bool flip)
        {
            ItemName = name;
            MeshTransform = new ItemMeshTransform();
            MeshTransform.IsFliped = flip;
        }*/
    }


}
/*public class NewMapLoadArgs
{
    public bool isLoadFromLocal = true;
    public List<GameMap.UserItemPropertyData> userData;
}*/